/**
* @file The following functions are for exploring basic ocaml types in C.
*
* todo: class, module
* @author gdhuang@ntu.edu.tw
*/

#ifndef _OCAML_TYPE_H_
#define _OCAML_TYPE_H_

#include <caml/mlvalues.h>

//string
#define Copy_string(v) (String_val(v))

//typedef enum {false, true} Bool;

typedef enum {Some, None} Option;

#define DECLARE_TYPE(TypeName) typedef value TypeName;

/**
* OCaml record is analogous to C structure.
*/
#define DECLARE_RECORD_TYPE(TypeName) DECLARE_TYPE(TypeName)


/**
* OCaml sum is analogous to C union.
* Use DECLARE_SUM_TYPE() and DECLARE_SUM_TAG() to declare a ocaml sum in C.
*
* Field( Sum , I ),Tag_val(sum)
*/
#define DECLARE_SUM_TYPE(TypeName) DECLARE_TYPE(TypeName)

#define DECLARE_SUM_TAG(args...) enum { args };
 

/**
* tuple
* 
* Field( Tuple , I )
*/
DECLARE_TYPE(OCamlTuple)



/**
* OCaml list is analogous to C link list.
*/
DECLARE_TYPE(OCamlList)

#define LIST_DATA(List) Field( List , 0)

#define LIST_NEXT(List) Field( List , 1)

#define NIL Val_int(0)


int LIST_LENGTH(OCamlList list);


/**
* 'a option =
* | None
* | Some (data:'a)
*/

Option is_None(value v);

#define Some_val(v) Field(v,0)

/**
* 'a ref
*/
#define DEREF(v) Field(v, 0)


DECLARE_TYPE(OCamlOutChannel)


#endif
